// 题意：
// 现在有一个n*m(<=300)的棋盘a，a[i][j]要么是0要么是1, 现在已知一个
// (n-1)*(m-1)的棋盘b， b[i][j]=a[i][j]+a[i+1][j]+a[i][j+1]+a[i+1][j+1]，
// 问是不是可以在知道b的情况下，还原出任意一组合法的a，如果不可以输出CORRUPT。
//
// 题解：
// 这个题很厉害。
// 首先可以知道 a[i][j]=b[i][j]-a[i+1][j]-a[i][j+1]-a[i+1][j+1]。
// 那么不断展开到边界i=n或j=m的情况，你会发现，a[i][j]只和
// a[n][j]，a[i][m], a[n][m]有关，系数可以通过预先的地推处理出来。
// （规律也可以这么去寻找）。
//
// 然后我们可以枚举a[n][m]，对于任意一个点的方程，我们枚举a[i][m]以及
// a[n][j]的值，如果它们的值导致a[i][j]不合法，那么说明这两种取值是不可以
// 同时存在的，这是一个2-sat问题，我们可以勾出图。
//
// 最后找到一组合法的a[n][j]以及a[i][m]的解，我们就可以推出整个棋盘了。
// 这个问题上由于是对称的构图，所以在找一组合法解的时候不需要复杂的反向
// 拓扑排序，只需要给每个联通块做个标记就行。（还需要加深理解）
//
// ml:run = $bin < input
// ml:opt = 0
// ml:ccf += -g
#include <iostream>
#include <stack>
#include <vector>
#include <cstring>

int const maxn = 400;
int a[maxn][maxn];
int b[maxn][maxn];
int c[maxn][maxn];
int n, m;

// 1 ~ n + m - 1 for true, n + m ~ 2 * (n + m - 1) for false
std::vector<std::vector<int>> graph;

int low[maxn * 4], dfn[maxn * 4], color[maxn * 4];
int head[maxn * 4], label[maxn * 4];
bool instack[maxn * 4];
int tick, color_tick;
std::stack<int> stk;

void tarjan(int u)
{
	low[u] = dfn[u] = ++tick;
	stk.push(u);
	instack[u] = true;
	for (auto v : graph[u]) {
		if (!dfn[v]) {
			tarjan(v);
			low[u] = std::min(low[u], low[v]);
		} else if (instack[v])
			low[u] = std::min(low[u], dfn[v]);
	}
	if (low[u] == dfn[u]) {
		int t;
		head[++color_tick] = u;
		do { t = stk.top(); stk.pop(); color[t] = color_tick; instack[t] = false; }
		while (t != u);
	}
}

void dfs(int x, int y)
{
    if (x == n || y == m) { c[x][y] = 0; return; }
    if (c[x][y] >= 0) return;
    dfs(x + 1, y);
    dfs(x, y + 1);
    dfs(x + 1, y + 1);
    c[x][y] = b[x][y] - c[x + 1][y] - c[x][y + 1] - c[x + 1][y + 1];
}

bool inrange(int x, int l, int r)
{
    return l <= x && x <= r;
}

void add_edge(int u, int v)
{
    /* std::cerr << u << " " << v << "\n"; */
    graph[u].push_back(v);
}

int rev(int x)
{
    if (x <= n + m - 1) return x + n + m - 1;
    else return x - (n + m - 1);
}

void conflict(int ti/*, m*/, int /*n, */tj, int v1, int v2)
{
    int id1 = ti, id2 = n + tj;
    if (!v1) id1 += n + m - 1;
    if (!v2) id2 += n + m - 1;
    add_edge(id1, rev(id2));
    add_edge(id2, rev(id1));
}

void init()
{
    graph.clear();
    graph.resize(2 * (n + m - 1) + 7);
	std::memset(dfn, 0, sizeof(dfn));
	std::memset(instack, 0, sizeof(instack));
	while (!stk.empty()) stk.pop();
	tick = color_tick = 0;
}

void corrupt()
{
    std::cout << "CORRUPT\n";
    exit(0);
}

void work()
{
    // iterate a[n][m]
    bool sol = false;
    for (int nm = 0; nm <= 1; nm++) {
        init();
        for (int i = 1; i < n; i++)
            for (int j = 1; j < m; j++) {
                int opt1 = -((n - i) & 1); if (!opt1) opt1 = 1;
                int opt2 = -((m - j) & 1); if (!opt2) opt2 = 1;
                int opt3 = -opt1 * opt2;
                for (int ti = 0; ti <= 1; ti++)
                    for (int tj = 0; tj <= 1; tj++) {
                        int tmp = c[i][j] + opt1 * ti + opt2 * tj + opt3 * nm;
                        if (!inrange(tmp, 0, 1)) conflict(i, j, tj, ti);
                    }
            }

        for (int i = 1; i <= 2 * (n + m - 1); i++)
            if (!dfn[i]) tarjan(i);

        /* for (int i = 1; i <= 2 * (n + m - 1); i++) std::cerr << color[i] << " "; std::cerr << "\n"; */
        /* for (int i = 1; i <= color_tick; i++) std::cerr << head[i] << " "; std::cerr << "\n"; */

        std::memset(label, -1, sizeof(label));
        for (int i = 1; i <= color_tick; i++) {
            if (label[i] == -1) {
                label[i] = 1;
                label[color[rev(head[i])]] = 0;
            }
        }

        bool ok = true;
        for (int i = 1; i <= n + m - 1; i++)
            if (color[i] == color[rev(i)]) { ok = false; break; }
        if (!ok) continue;

        for (int i = 1; i < n; i++) a[i][m] = label[color[i]];
        for (int i = 1; i < m; i++) a[n][i] = label[color[n + i]];
        a[n][m] = nm;

        /* std::cerr << a[1][m] << " " << a[2][m] << " " << a[n][1] << " " << a[n][2] << "\n"; */

        for (int i = 1; i < n; i++) {
            for (int j = 1; j < m; j++) {
                int opt1 = -((n - i) & 1); if (!opt1) opt1 = 1;
                int opt2 = -((m - j) & 1); if (!opt2) opt2 = 1;
                int opt3 = -opt1 * opt2;
                a[i][j] = c[i][j] + opt1 * a[n][j] + opt2 * a[i][m] + opt3 * nm;
                if (!inrange(a[i][j], 0, 1)) { ok = false; break; }
            }
        }
        if (!ok) continue;
        sol = true;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) std::cout << a[i][j];
            std::cout << "\n";
        }
        break;
    }
    if (!sol) corrupt();
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    std::cin >> n >> m;
    std::memset(c, -1, sizeof(c));
    for (int i = 1; i < n; i++)
        for (int j = 1; j < m; j++) {
            char ch; std::cin >> ch;
            b[i][j] = ch - '0';
        }

    dfs(1, 1);

    work();
}

